home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / access / common / printtup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  7.0 KB  |  319 lines

  1. /*
  2.  * printtup.c --
  3.  *    Routines to print out tuples to the standard output.
  4.  */
  5.  
  6. #include <sys/file.h>
  7. #include <stdio.h>
  8. #include <strings.h>
  9.  
  10. #include "tmp/postgres.h"
  11.  
  12. RcsId("$Header: /private/postgres/src/access/common/RCS/printtup.c,v 1.7 1992/03/06 22:17:36 clarsen Exp $");
  13.  
  14. #include "access/heapam.h"
  15. #include "access/htup.h"
  16. #include "access/skey.h"
  17. #include "storage/buf.h"
  18. #include "utils/memutils.h"
  19. #include "utils/fmgr.h"
  20. #include "utils/log.h"
  21.  
  22. #include "catalog/syscache.h"
  23. #include "catalog/pg_type.h"
  24.  
  25. /* ----------------
  26.  *    convtypeinfo
  27.  *
  28.  *    Converts an old-style typeinfo (struct attribute array) into
  29.  *    the new-style typeinfo (struct attribute (*) array).
  30.  *
  31.  *    XXX temporary, but still called by the executor.
  32.  * ----------------
  33.  */
  34. struct attribute **
  35. convtypeinfo(natts, att)
  36.     int         natts;
  37.     struct attribute    *att;
  38. {
  39.     struct    attribute *ap, **rpp, **retatt;
  40.     
  41.     rpp = retatt = (struct attribute **) 
  42.     palloc(natts * sizeof(*rpp) + natts * sizeof(**rpp));
  43.     MemoryCopy(rpp + natts, att, natts * sizeof(**rpp));
  44.     
  45.     ap = (struct attribute *)(rpp + natts);
  46.     while (--natts >= 0)
  47.     *rpp++ = ap++;
  48.     return(retatt);
  49. }
  50.  
  51. /* ----------------------------------------------------------------
  52.  *    printtup / debugtup support
  53.  * ----------------------------------------------------------------
  54.  */
  55. /* ----------------
  56.  *    typtoout - used by printtup and debugtup
  57.  * ----------------
  58.  */
  59. ObjectId
  60. typtoout(type)
  61.     ObjectId    type;
  62. {
  63.     HeapTuple    typeTuple;
  64.  
  65.     typeTuple = SearchSysCacheTuple(TYPOID,
  66.                     (char *) type,
  67.                     (char *) NULL,
  68.                     (char *) NULL,
  69.                     (char *) NULL);
  70.  
  71.     if (HeapTupleIsValid(typeTuple))
  72.     return((ObjectId)
  73.            ((TypeTupleForm) GETSTRUCT(typeTuple))->typoutput);
  74.  
  75.     elog(WARN, "typtoout: Cache lookup of type %d failed", type);
  76.     return(InvalidObjectId);
  77. }
  78.  
  79. ObjectId
  80. gettypelem(type)
  81.     ObjectId    type;
  82.  
  83. {
  84.     HeapTuple    typeTuple;
  85.  
  86.     typeTuple = SearchSysCacheTuple(TYPOID,
  87.                     (char *) type,
  88.                     (char *) NULL,
  89.                     (char *) NULL,
  90.                     (char *) NULL);
  91.  
  92.     if (HeapTupleIsValid(typeTuple))
  93.     return((ObjectId)
  94.            ((TypeTupleForm) GETSTRUCT(typeTuple))->typelem);
  95.  
  96.     elog(WARN, "typtoout: Cache lookup of type %d failed", type);
  97.     return(InvalidObjectId);
  98. }
  99.  
  100. /* ----------------
  101.  *    printtup
  102.  * ----------------
  103.  */
  104. void
  105. printtup(tuple, typeinfo)
  106.     HeapTuple        tuple;
  107.     struct attribute     *typeinfo[];
  108. {
  109.     int        i, j, k;
  110.     char    *outputstr, *attr;
  111.     Boolean    isnull;
  112.     ObjectId    typoutput;
  113.     
  114.     /* ----------------
  115.      *    tell the frontend to expect new tuple data
  116.      * ----------------
  117.      */
  118.     pq_putnchar("D", 1);
  119.     
  120.     /* ----------------
  121.      *    send a bitmap of which attributes are null
  122.      * ----------------
  123.      */
  124.     j = 0;
  125.     k = 1 << 7;
  126.     for (i = 0; i < tuple->t_natts; ) {
  127.     attr = heap_getattr(tuple, InvalidBuffer, ++i, typeinfo, &isnull);
  128.     if (!isnull)
  129.         j |= k;
  130.     k >>= 1;
  131.     if (!(i & 7)) {
  132.         pq_putint(j, 1);
  133.         j = 0;
  134.         k = 1 << 7;
  135.     }
  136.     }
  137.     if (i & 7)
  138.     pq_putint(j, 1);
  139.     
  140.     /* ----------------
  141.      *    send the attributes of this tuple
  142.      * ----------------
  143.      */
  144.     for (i = 0; i < tuple->t_natts; ++i) {
  145.     attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
  146.     typoutput = typtoout((ObjectId) typeinfo[i]->atttypid);
  147.     
  148.     if (!isnull && ObjectIdIsValid(typoutput)) {
  149.         outputstr = fmgr(typoutput, attr, gettypelem(typeinfo[i]->atttypid));
  150.         pq_putint(strlen(outputstr)+4, 4);
  151.         pq_putnchar(outputstr, strlen(outputstr));
  152.         pfree(outputstr);
  153.     }
  154.     }
  155. }
  156.  
  157. /* ----------------
  158.  *    printatt
  159.  * ----------------
  160.  */
  161. void
  162. printatt(attributeId, attributeP, value)
  163.     unsigned        attributeId;
  164.     struct attribute    *attributeP;
  165.     char            *value;
  166. {
  167.     printf("\t%2d: %s%s%s%s\t(typeid = %lu, len = %d, byval = %c)\n",
  168.        attributeId,
  169.        attributeP->attname,
  170.        value != NULL ? " = \"" : "",
  171.        value != NULL ? value : "",
  172.        value != NULL ? "\"" : "",
  173.        attributeP->atttypid,
  174.        attributeP->attlen,
  175.        attributeP->attbyval ? 't' : 'f');
  176. }
  177.  
  178. /* ----------------
  179.  *    showatts
  180.  * ----------------
  181.  */
  182. showatts(name, natts, attinfo)
  183.     char            *name;
  184.     int            natts;
  185.     struct attribute    *attinfo[];
  186. {
  187.     register int    i;
  188.     
  189.     puts(name);
  190.     for (i = 0; i < natts; ++i)
  191.     printatt((unsigned) i+1, attinfo[i], (char *) NULL);
  192.     printf("\t----\n");
  193. }
  194.  
  195. /* ----------------
  196.  *    debugtup
  197.  * ----------------
  198.  */
  199. void
  200. debugtup(tuple, typeinfo)
  201.     HeapTuple        tuple;
  202.     struct attribute     *typeinfo[];
  203. {
  204.     register int    i;
  205.     char        *attr, *value;
  206.     Boolean        isnull;
  207.     ObjectId        typoutput;
  208.     
  209.     for (i = 0; i < tuple->t_natts; ++i) {
  210.     attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
  211.     typoutput = typtoout((ObjectId) typeinfo[i]->atttypid);
  212.     
  213.     if (!isnull && ObjectIdIsValid(typoutput)) {
  214.         value = fmgr(typoutput, attr, gettypelem(typeinfo[i]->atttypid));
  215.         printatt((unsigned) i+1, typeinfo[i], value);
  216.         pfree(value);
  217.     }
  218.     }
  219.     printf("\t----\n");
  220. }
  221.  
  222.  
  223. /* ----------------
  224.  *    printtup_internal
  225.  *      Protocol expects either T, D, C, E, or N.
  226.  *      We use a different data prefix, e.g. 'B' instead of 'D' to
  227.  *      indicate a tuple in internal (binary) form.
  228.  *
  229.  *      This is same as printtup, except we don't use the typout func.
  230.  * ----------------
  231.  */
  232. void
  233. printtup_internal(tuple, typeinfo)
  234.     HeapTuple        tuple;
  235.     struct attribute     *typeinfo[];
  236. {
  237.     int        i, j, k;
  238.     char    *outputstr, *attr;
  239.     Boolean    isnull;
  240.     ObjectId    typoutput;
  241. #if 0
  242.     FILE *f = fopen("/dev/ttyp0","w");
  243. #endif
  244.     
  245.     /* ----------------
  246.      *    tell the frontend to expect new tuple data
  247.      * ----------------
  248.      */
  249.     pq_putnchar("B", 1);
  250.     
  251.     /* ----------------
  252.      *    send a bitmap of which attributes are null
  253.      * ----------------
  254.      */
  255.     j = 0;
  256.     k = 1 << 7;
  257.     for (i = 0; i < tuple->t_natts; ) {
  258.     attr = heap_getattr(tuple, InvalidBuffer, ++i, typeinfo, &isnull);
  259.     if (!isnull)
  260.       j |= k;
  261.     k >>= 1;
  262.     if (!(i & 7)) {
  263.         pq_putint(j, 1);
  264.         j = 0;
  265.         k = 1 << 7;
  266.     }
  267.     }
  268.     if (i & 7)
  269.       pq_putint(j, 1);
  270.     
  271.     /* ----------------
  272.      *    send the attributes of this tuple
  273.      * ----------------
  274.      */
  275.     for (i = 0; i < tuple->t_natts; ++i) {
  276.     int len;
  277.  
  278.     attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
  279.     len = typeinfo[i]->attlen;
  280.     if (!isnull) {
  281.         /* # of bytes, and opaque data */
  282.         switch (len) {
  283.           case -1: {
  284.           /* variable length, assume a varlena structure */
  285.           int l = VARSIZE(PointerGetDatum(attr));
  286.           pq_putint(l,4);
  287.           pq_putnchar(VARDATA(PointerGetDatum(attr)),l);
  288. #if 0
  289.           {
  290.           char *d = VARDATA(PointerGetDatum(attr));
  291.           fprintf(f,"length %d data %x%x%x%x\n",l,*d,*(d+1),*(d+2),*(d+3));
  292.           }
  293. #endif
  294.           }   
  295.         break;
  296.  
  297.           default:        /* fixed size */
  298.            if (typeinfo[i]->attbyval) {
  299.           pq_putint(len,4);
  300.           pq_putnchar(&attr,len);
  301. #if 0
  302.               fprintf(f,"byval length %d data %d\n",len,attr);
  303. #endif
  304.            } else {
  305.           pq_putint(len,4);
  306.           pq_putnchar(attr,len);
  307. #if 0
  308.           fprintf(f,"byref length %d data %x\n",len,attr);
  309. #endif
  310.            }
  311.             break;
  312.         }
  313.     }
  314.     }
  315. #if 0
  316.     fclose(f);
  317. #endif
  318. }
  319.